1、 GPIO 子系统简介
	引脚配置为 GPIO 模式后（可以通过 pinctrl 子系统配置，默认情况下 pinctrl 子系统会将引脚复用为 GPIO 模式）
，便可使用 GPIO 子系统来控制引脚， GPIO 子系统可方便驱动开发者使用 GPIO ，驱动开发者在设备树中添加 GPIO 相关
信息后就可以在驱动程序中使用 GPIO 子系统提供的 API 函数来操作 GPIO。
2、 在设备树中使用 GPIO
	在需要使用 GPIO 的设备树节点中加入描述 GPIO 的属性即可（属性一般采用 xxx-gpios 格式命名），如下是一个使
用 GPIO 的 LED 设备树节点(两种写法均可)：
	led {
		compatible = "atk,led";
		led-gpios = <&gpioi 0 GPIO_ACTIVE_LOW>,
					<&gpioi 1 GPIO_ACTIVE_LOW>;
		status = "okay";
	};
	led {
		compatible = "atk,led";
		//数据格式：GPIO组 IO号 属性 GPIO组 IO号 属性 ......
		//常用属性有：
		//          GPIO_OPEN_DRAIN 开漏输出
		//          GPIO_PULL_UP 上拉
		//          GPIO_PULL_DOWN 下拉
		//          GPIO_ACTIVE_HIGH 高电平有效
		//          GPIO_ACTIVE_LOW 低电平有效
		led-gpios = <&gpioi 0 GPIO_ACTIVE_LOW
					&gpioi 1 GPIO_ACTIVE_LOW>;
		status = "okay";
	};
3、基于 GPIO 描述符的 API
	此版接口函数以 gpiod_ 开头，常用的 API 如下：
	/* 获取 GPIO ，它相当于基于 GPIO 编号的 API 中的 of_get_named_gpio 或 of_get_gpio_flags 加 gpio_request
	 * 或 devm_gpio_request
	 * dev 要获取 GPIO 的设备
	 * con_id 引用 GPIO 节点的设备树属性前缀，设备树属性名称必须是 xxx-gpios 或 xxx-gpio 格式命名
	 * idx 表示获取 con_id 的第 idx 个引脚
	 * flags 指定方向和默认输出：
	 *       GPIOD_ASIS 或0 不进行初始化配置
	 *       GPIOD_IN 初始化为输入
	 *       GPIOD_OUT_LOW 初始化为输出并输出逻辑0
	 *       GPIOD_OUT_HIGH 初始化为输出并输出逻辑1
	 *       GPIOD_OUT_LOW_OPEN_DRAIN 与 GPIOD_OUT_LOW 一样，但是采用开漏输出
	 *       GPIOD_OUT_HIGH_OPEN_DRAIN 与 GPIOD_OUT_HIGH 一样，但是采用开漏输出
	 **/
	struct gpio_desc *gpiod_get(struct device *dev, const char *con_id,
		enum gpiod_flags flags)
	struct gpio_desc *gpiod_get_index(struct device *dev, const char *con_id,
		unsigned int idx, enum gpiod_flags flags)
	struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id,
		enum gpiod_flags flags)
	struct gpio_desc *devm_gpiod_get_index(struct device *dev, const char *con_id,
		unsigned int idx, enum gpiod_flags flags)
	/* 释放 GPIO ，执行 gpiod_get 的反操作，采用 devm_xxx 函数获取的 GPIO 无需调用此函数释放，他相当于基于 
	 * GPIO 编号的 API 中的 gpio_free
	 * desc GPIO描述符
	 **/
	void gpiod_put(struct gpio_desc *desc)
	void gpiod_free(struct gpio_desc *desc)
	/* 设置 GPIO 为输入
	 * desc GPIO描述符
	 **/
	int gpiod_direction_input(struct gpio_desc *desc)
	/* 设置 GPIO 为输入
	 * desc GPIO描述符
	 * value 默认输出的逻辑值
	 **/
	int gpiod_direction_output(struct gpio_desc *desc, int value)
	/* 获取 GPIO 的逻辑电平
	 * desc GPIO描述符
	 **/
	int gpiod_get_value(const struct gpio_desc *desc)
	/* 设置 GPIO 的逻辑电平
	 * desc GPIO描述符
	 * value 输出的逻辑值
	 **/
	int gpiod_set_value(struct gpio_desc *desc, int value)
4、基于 GPIO 编号的 API
	/* 从设备树中获取 GPIO 编号，其中 of_get_gpio_flags 必须要求描述 GPIO 的属性名称为 gpios
	 * np 设备树节点
	 * propname 描述 GPIO 的设备树属性名称
	 * index 表示获取 propname 第 index 个引脚
	 * flags GPIO 属性，常用的属性有：
	 *       OF_GPIO_ACTIVE_LOW 低电平有效
	 *       OF_GPIO_SINGLE_ENDED 高电平有效
	 *       OF_GPIO_OPEN_DRAIN 开漏输出
	 *       OF_GPIO_PULL_UP 上拉
	 *       OF_GPIO_PULL_DOWN 下拉
	 **/
	int of_get_named_gpio(struct device_node *np, const char *propname,
		int index)
	int of_get_named_gpio_flags(struct device_node *np, const char *propname,
		int index, enum of_gpio_flags *flags)
	int of_get_gpio_flags(struct device_node *np, int index,
		enum of_gpio_flags *flags)
	/* 获取描述 GPIO 的属性中描述的 GPIO 个数，其中 of_gpio_count 必须要求描述 GPIO 的属性名称为 gpios
	 * np 设备树节点
	 * propname 描述 GPIO 的设备树属性名称
	 **/
	int of_gpio_named_count(struct device_node *np, const char* propname)
	int of_gpio_count(struct device_node *np)
	/* 获取 GPIO
	 * gpio GPIO 编号
	 * label 标签
	 **/
	int gpio_request(unsigned gpio, const char *label)
	/* 释放 GPIO
	 * gpio GPIO 编号
	 **/
	void gpio_free(unsigned gpio)
	/* 设置 GPIO 为输入
	 * gpio GPIO 编号
	 **/
	int gpio_direction_input(unsigned gpio)
	/* 设置 GPIO 输出
	 * gpio GPIO 编号
	 * value 默认输出电平
	 **/
	int gpio_direction_output(unsigned gpio, int value)
	/* 获取 GPIO 为输入电平
	 * gpio GPIO 编号
	 **/
	int gpio_get_value(unsigned gpio)
	/* 设置 GPIO 输出电平
	 * gpio GPIO 编号
	 * value 默认输出电平
	 **/
	void gpio_set_value(unsigned gpio, int value)
